package com.onesports.intelligent.k12.polarlight.service.course;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.onesports.intelligent.k12.polarlight.common.errors.exceptions.BusinessException;
import com.onesports.intelligent.k12.polarlight.constant.CodeConstants;
import com.onesports.intelligent.k12.polarlight.domain.dto.course.CourseClassifySaveOrUpdateDTO;
import com.onesports.intelligent.k12.polarlight.domain.dto.course.CourseSubLevelSaveOrUpdateDTO;
import com.onesports.intelligent.k12.polarlight.domain.entity.course.Course;
import com.onesports.intelligent.k12.polarlight.domain.entity.course.CourseClassify;
import com.onesports.intelligent.k12.polarlight.domain.entity.course.CourseSubLevel;
import com.onesports.intelligent.k12.polarlight.domain.vo.course.CourseClassificationVO;
import com.onesports.intelligent.k12.polarlight.domain.vo.course.CourseClassifyVO;
import com.onesports.intelligent.k12.polarlight.domain.vo.course.CourseSubLevelVO;
import com.onesports.intelligent.k12.polarlight.service.course.manage.CourseClassifyService;
import com.onesports.intelligent.k12.polarlight.service.course.manage.CourseSubLevelService;
import com.onesports.intelligent.k12.polarlight.util.BeanCopyUtil;
import com.onesports.intelligent.k12.polarlight.util.CodeUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author FPH
 * @since 2022年7月8日14:31:17
 * 运营端-基础数据配置-课程分类
 */
@Service
@RequiredArgsConstructor
public class CourseClassificationService {
    private final CourseClassifyService courseClassifyService;
    private final CourseSubLevelService courseSubLevelService;
    private final CourseService courseService;
    private final CodeUtils codeUtils;

    /**
     * 分页查询
     * @param current
     * @param size
     * @param name
     * @return
     */
    public IPage<CourseClassificationVO> getClassificationList(Long current,Long size,String name){
        Page<CourseClassificationVO> resultPage = new Page<>();
        Page<CourseClassify> page = new Page<>(current, size);
        LambdaQueryWrapper<CourseClassify> CourseClassifyWrapper = new LambdaQueryWrapper<>();
        CourseClassifyWrapper.eq(StringUtils.isNotEmpty(name),CourseClassify::getClassifyName,name);
        CourseClassifyWrapper.orderByDesc(CourseClassify::getCreatedDate);
        Page<CourseClassify> classifyPage = courseClassifyService.page(page, CourseClassifyWrapper);
        List<CourseClassify> classifyList = classifyPage.getRecords();
        if(CollectionUtils.isEmpty(classifyList)){
            return resultPage;
        }
        Map<String, List<CourseSubLevel>> map = courseSubLevelService.list(new LambdaQueryWrapper<CourseSubLevel>()
                        .in(CourseSubLevel::getClassifyId, classifyList
                                .stream()
                                .map(CourseClassify::getId)
                                .collect(Collectors.toList())))
                .stream()
                .collect(Collectors.groupingBy(CourseSubLevel::getClassifyId));

        //排除集合，否则集合类型异常
        BeanUtils.copyProperties(page,resultPage,"records");
        //单独挑出records进行BeanUtils操作
        List<CourseClassificationVO> courseClassificationVOS = BeanCopyUtil.copyListProperties(page.getRecords(), CourseClassificationVO::new);
        resultPage.setRecords(courseClassificationVOS);

        resultPage.getRecords().forEach(i->{
            List<CourseSubLevel> mapResult = map.get(i.getId());
            if(CollectionUtils.isEmpty(mapResult)){
                mapResult=new ArrayList<CourseSubLevel>();
            }
            i.setSubLevelList(BeanCopyUtil.copyListProperties(mapResult,CourseSubLevelVO::new));
        });
        return resultPage;
    }

    /**
     * 获取课程分类名称列表下拉
     * @return
     */
    public List<CourseClassifyVO> queryClassifyNameList(){
        return courseClassifyService.queryClassifyNameList();
    }

    /**
     * 通用删除课程分类、课程分阶
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean remove(String id){
        //判断id属于分类还是分阶
        CourseClassify classify = courseClassifyService.getById(id);
        if(classify!=null){
            List<CourseSubLevel> list = courseSubLevelService.list(new LambdaQueryWrapper<CourseSubLevel>()
                    .eq(CourseSubLevel::getClassifyId, id));
            if(CollectionUtils.isNotEmpty(list)){
                throw new BusinessException("该分类已关联分阶，无法删除");
            }
            checkCourseCls(id);
            return courseClassifyService.removeById(id);
        }else{
            checkCourseSub(id);
        }
        return courseSubLevelService.removeById(id);
    }

    /**
     * 课程分类新增修改通用接口
     * @param courseClassifySaveOrUpdateDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean classifySaveOrUpdate(CourseClassifySaveOrUpdateDTO courseClassifySaveOrUpdateDTO){
        CourseClassifySaveOrUpdateDTO dto = courseClassifyService.checkId(courseClassifySaveOrUpdateDTO);
        if(StringUtils.isNotEmpty(dto.getId())){
            checkCourseCls(dto.getId());
        }
        Boolean checkBoolean = courseClassifyService.checkName(dto.getClassifyName(), dto.getId());
        if(!checkBoolean){
            throw new BusinessException("名称重复");
        }
        CourseClassify courseClassify = new CourseClassify();
        BeanUtils.copyProperties(dto,courseClassify);
        if(StringUtils.isEmpty(courseClassify.getId())){
            //生成随机数字编码
            courseClassify.setClassifyCode(codeUtils.autoSerialNumberNoPrefix(CodeConstants.COURSE_TYPE,2));
        }

        return courseClassifyService.saveOrUpdate(courseClassify);
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean subLevelSaveOrUpdate(CourseSubLevelSaveOrUpdateDTO courseSubLevelSaveOrUpdateDTO){
        CourseSubLevelSaveOrUpdateDTO dto = courseSubLevelService.checkId(courseSubLevelSaveOrUpdateDTO);
        Boolean checkName = courseSubLevelService.checkName(dto.getSubLevelName(), dto.getId(),dto.getClassifyId());
        if(!checkName){
            throw new BusinessException("名称重复");
        }
        CourseSubLevel courseSubLevel = new CourseSubLevel();
        BeanUtils.copyProperties(dto,courseSubLevel);

        //校验分类id是否存在
        CourseClassify courseClassify = courseClassifyService.getById(courseSubLevel.getClassifyId());
        if(courseClassify==null){
            throw new BusinessException("此分类ID不存在");
        }

        if(StringUtils.isEmpty(courseSubLevel.getId())){
            //生成随机数字编码
            String code = courseClassifyService.getById(courseSubLevel.getClassifyId()).getClassifyCode();
            courseSubLevel.setSubLevelCode(code+codeUtils.autoSerialNumberNoPrefix(CodeConstants.COURSE_LEVEL+code,2));
        }else{
            checkCourseSub(courseSubLevel.getId());
        }


        //年龄校验
        if(courseSubLevel.getMaxAge()!=null&&courseSubLevel.getMinAge()!=null&&courseSubLevel.getMaxAge()< courseSubLevel.getMinAge()){
            throw new BusinessException("最大年龄不可超过最小年龄");
        }
        return courseSubLevelService.saveOrUpdate(courseSubLevel);
    }

    /**
     * 判断在course是否存在cls
     */
    public void checkCourseCls(String clsId){
        List<Course> list = courseService.list(new LambdaQueryWrapper<Course>().eq(Course::getCourseClassifyId, clsId));
        if(CollectionUtils.isNotEmpty(list)){
            throw new BusinessException("该课程分类已有关联课程使用，不允许执行此操作");
        }
    }

    /**
     * 判断在course是否存在sub
     */
    public void checkCourseSub(String subId){
        List<Course> list = courseService.list(new LambdaQueryWrapper<Course>().eq(Course::getCourseSubLevelId, subId));
        if(CollectionUtils.isNotEmpty(list)){
            throw new BusinessException("该课程分阶已有关联课程使用，不允许执行此操作");
        }
    }

}
